package com.bwie.cart.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bwie.cart.domain.dto.InsertCartDTO;
import com.bwie.cart.domain.po.CartItemPO;
import com.bwie.cart.domain.po.CartPO;
import com.bwie.cart.domain.vo.CartItemVO;
import com.bwie.cart.domain.vo.CartVO;
import com.bwie.cart.mapper.CartClientMapper;
import com.bwie.cart.mapper.CartItemClientMapper;
import com.bwie.cart.service.CartClientService;
import com.bwie.common.core.constant.Constants;
import com.bwie.common.core.domain.Result;
import com.bwie.common.core.exception.ServiceException;
import com.bwie.common.redis.service.RedisService;
import com.bwie.common.security.utils.SecurityUtils;
import com.bwie.system.api.RemoteProductService;
import com.bwie.system.api.domain.SkuInfo;
import com.bwie.system.api.domain.SysUser;
import com.bwie.system.api.model.LoginUser;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
public class CartClientServiceImpl implements CartClientService {
    @Autowired
    private CartClientMapper cartMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private CartItemClientMapper cartItemMapper;

    @Autowired
    private RemoteProductService remoteProductService;

    /**
     * 用户端
     * 获取购物车列表
     * @return
     */
    @Override
    public List<CartVO> getCartList() {
        //获取登录人信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getSysUser();

        //根据userId查询购物车信息
        CartPO cartPO = new CartPO();
        cartPO.setUserId(user.getUserId());
//        cartPO.setUserId(1L);
        List<CartVO> cartVOS = cartMapper.selectCartList(cartPO);

        if (!CollectionUtils.isEmpty(cartVOS)) {
            // 获取所有与用户相关的购物车键
            Collection<String> cartKeys = redisService.keys("CART:" + user.getUserId());
//            Collection<String> cartKeys = redisService.keys("CART:" + 1L);

            // 创建一个映射来存储每个购物车ID对应的CartItemVO列表
            Map<Long, List<CartItemVO>> cartItemMap = new HashMap<>();

            // 批量获取所有购物车详情信息并解析为CartItemVO对象
            for (String cartKey : cartKeys) {
                Map<String, Object> cartItemMapFromRedis = redisService.getCacheMap(cartKey);
                for (Object cartItemObj : cartItemMapFromRedis.values()) {
                    String cartItemJson = JSON.toJSONString(cartItemObj);
                    CartItemVO cartItemVO = JSONObject.parseObject(cartItemJson, CartItemVO.class);
                    cartItemMap.computeIfAbsent(cartItemVO.getCartId(), k -> new ArrayList<>()).add(cartItemVO);
                }
            }

            // 更新每个CartVO中的CartItemVO列表
            for (CartVO cartVO : cartVOS) {
                cartVO.setCartItemVos(cartItemMap.getOrDefault(cartVO.getId(), Collections.emptyList()));
            }

            //redis中查询不到就到数据库查
            if (CollectionUtils.isEmpty(cartItemMap.values())){
                //从数据库中获取所有购物车详情信息
                CartItemPO cartItemPO = new CartItemPO();
                List<CartItemPO> cartItemPOS = cartItemMapper.selectCartItemList(cartItemPO);
                for (CartItemPO itemPO : cartItemPOS) {
                    //根据skuId获取sku信息详细信息方法
                    SkuInfo skuInfo = getSkuInfo(itemPO.getSkuId());

                    CartItemVO cartItemVO = new CartItemVO();
                    //将查询到的sku商品信息copy到购物车详情模型中
                    BeanUtils.copyProperties(skuInfo, cartItemVO);
                    cartItemVO.setCount(itemPO.getCount());
                    cartItemVO.setCartId(itemPO.getCartId());
                    cartItemVO.setCheckedStatus(itemPO.getCheckedStatus());
                    cartItemMap.computeIfAbsent(cartItemVO.getCartId(), k -> new ArrayList<>()).add(cartItemVO);
                    //将整理好的购物车详情存入redis中
                    redisService.setCacheMapValue("CART:" + user.getUserId(), JSONObject.toJSONString(itemPO.getSkuId()),cartItemVO);
//                    redisService.setCacheMapValue("CART:" + 1L, JSONObject.toJSONString(itemPO.getSkuId()),cartItemVO);
                }

                // 更新每个CartVO中的CartItemVO列表
                for (CartVO cartVO : cartVOS) {
                    cartVO.setCartItemVos(cartItemMap.getOrDefault(cartVO.getId(), Collections.emptyList()));
                }
            }
        }


        return cartVOS;
    }

    /**
     * 远程调用获取sku信息详细信息方法
     * @param skuId
     * @return
     */
    private SkuInfo getSkuInfo(Long skuId) {
        Result<SkuInfo> result = remoteProductService.getInfo(skuId);

        if (result.getCode() == Constants.FAIL){
            throw new ServiceException(result.getMsg());
        }

        SkuInfo skuInfo = result.getData();
        return skuInfo;
    }

    /**
     * 用户端
     * 添加购物车
     */
    @Override
    public void insertCart(InsertCartDTO insertCartDTO) {
        //获取登录人信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getSysUser();

        // 创建一个购物车对象，并设置其所属用户ID，准备查询该用户的购物车记录
        CartPO cartPO = new CartPO();
        cartPO.setUserId(user.getUserId());

        // 查询该用户的所有购物车记录
        List<CartVO> carts = cartMapper.selectCartList(cartPO);

        //根据skuId获取sku信息详细信息方法
        SkuInfo skuInfo = getSkuInfo(insertCartDTO.getSkuId());

        // 提取现有购物车中所有商家ID到列表中
        List<Long> sellerIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(carts)){
            for (CartVO cartVO : carts) {
                sellerIds.add(cartVO.getSellerId());
            }
        }

        // 判断Redis缓存中是否有当前登录用户的购物车信息，或者购物车中是否已包含相同商家的商品
        if (!redisService.hasKey("CART:" + user.getUserId()) || !sellerIds.contains(skuInfo.getSellerId())) {
            // 如果没有，则添加一条新的购物车及购物车详情信息

            // 创建一个新的购物车条目
            CartPO cart = new CartPO();
            cart.setUserId(user.getUserId());
            cart.setSellerId(skuInfo.getSellerId());

            // 插入新的购物车记录到数据库
            cartMapper.insertCart(cart);

            // 创建一个新的购物车商品详情Vo对象
            CartItemVO cartItemVo = new CartItemVO();
            // 将商品信息复制到购物车详情Vo对象中
            BeanUtils.copyProperties(skuInfo, cartItemVo);
            cartItemVo.setCount(insertCartDTO.getCount());
            cartItemVo.setCheckedStatus(1); // 默认选中状态为1（true）
            cartItemVo.setCartId(cart.getId());

            // 将购物车详情信息保存到Redis缓存中
            redisService.setCacheMapValue("CART:" + user.getUserId(), String.valueOf(insertCartDTO.getSkuId()), cartItemVo);
        }else {
            // 如果存在，则继续判断该购物车中是否有该商品详情信息

            // 从Redis缓存中获取购物车商品详情信息
            Object cartItemVoObj = redisService.getCacheMapValue("CART:" + user.getUserId(), String.valueOf(insertCartDTO.getSkuId()));
            String cartItemVoJson = JSONObject.toJSONString(cartItemVoObj);
            CartItemVO cartItemVo = JSONObject.parseObject(cartItemVoJson, CartItemVO.class);

            if (cartItemVo != null) {
                // 如果购物车中有该商品详情信息，则增加商品数量
                cartItemVo.setCount(cartItemVo.getCount() + insertCartDTO.getCount());
                redisService.setCacheMapValue("CART:" + user.getUserId(), String.valueOf(insertCartDTO.getSkuId()), cartItemVo);
            }   else {
                // 如果购物车中无该商品详情信息，则新增一条购物车详情信息

                // 再次远程调用根据skuId查询sku商品信息方法，并创建一个新的购物车商品详情Vo对象
                CartItemVO itemVo = new CartItemVO();
                BeanUtils.copyProperties(skuInfo, itemVo);
                itemVo.setCount(insertCartDTO.getCount());
                itemVo.setCheckedStatus(1);

                // 创建一个新的购物车条目，并查找是否存在相同的商家
                if (!CollectionUtils.isEmpty(carts)) {
                    for (CartVO cartVO : carts) {
                        if (Objects.equals(cartVO.getSellerId(), skuInfo.getSellerId())) {
                            itemVo.setCartId(cartVO.getId());
                        }
                    }
                }

                // 将新的购物车详情信息保存到Redis缓存中
                redisService.setCacheMapValue("CART:" + user.getUserId(), String.valueOf(insertCartDTO.getSkuId()), itemVo);
            }
        }
    }

    /**
     * 删除购物车
     * @param skuId
     */
    @Override
    public void delCart(Long skuId) {
        //获取登录人信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getSysUser();
        redisService.deleteCacheMapValue("CART:" + user.getUserId(), String.valueOf(skuId));
    }

    /**
     * 修改购物车详情商品数量
     * @param insertCartDTO
     */
    @Override
    public void updCartItemCount(InsertCartDTO insertCartDTO) {
        //获取登录人信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getSysUser();
        Object cartItemVoObj = redisService.getCacheMapValue("CART:" + user.getUserId(), String.valueOf(insertCartDTO.getSkuId()));
        String cartItemVoJson = com.alibaba.fastjson2.JSONObject.toJSONString(cartItemVoObj);
        CartItemVO cartItemVo = com.alibaba.fastjson2.JSONObject.parseObject(cartItemVoJson, CartItemVO.class);
        cartItemVo.setCount(insertCartDTO.getCount());
        redisService.setCacheMapValue("CART:" + user.getUserId(), String.valueOf(insertCartDTO.getSkuId()),cartItemVo);
    }

    /**
     * 获取购物车详情
     * @return
     */
    @Override
    public Result getCartItemList(Long skuId) {
        //用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userid = loginUser.getUserid();
        Object cacheMapValue = redisService.getCacheMapValue("CART:" + userid, String.valueOf(skuId));
        if (cacheMapValue != null) {
            String cartItemVoJson = com.alibaba.fastjson2.JSONObject.toJSONString(cacheMapValue);
            CartItemVO cartItemVo = com.alibaba.fastjson2.JSONObject.parseObject(cartItemVoJson, CartItemVO.class);
            return Result.success(cartItemVo);
        }
        return Result.error("不存在");
    }
}
